﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Testing_components;
using System.Security.Cryptography;
using System.Windows;

namespace BuildingTomorow
{
    public class DataAccess
    {
        private static DataAccess Instance;
        private buildingtomorowEntities databaseAccess;
        private List<PresentableSensor> _Allsensors = new List<PresentableSensor>();


        public List<PresentableSensor> GetPresentableSensors()
        {
            if (_Allsensors.Count == 0 || _Allsensors ==null)
            {
                List<SensorDB> senDB = GetSensors();
                _Allsensors = new List<PresentableSensor>();
                foreach (var item in senDB)
                {
                    _Allsensors.Add(new PresentableSensor(item));
                }
            }

            return _Allsensors;
        }

        public List<PresentableSensor> GetSensorsForGroup(int groupid)
        {
            List<int> sensorIds = databaseAccess.SensorGroupBridgeDBs.Where(x => x.GroupID == groupid).Select(x => x.SensorId).ToList();
            List<PresentableSensor> groupsen = new List<PresentableSensor>();

            foreach (var senID in sensorIds)
            {
                groupsen.Add(GetPresentableSensors().Where(x => x.ID == senID).First());
            }
            return groupsen;
        }
        public DataAccess()
        {
            databaseAccess = new buildingtomorowEntities();

        }
        public bool isAlive()
        {


            return !(databaseAccess.Connection.State.ToString() == "Closed");
        }
        public List<SensorDB> GetSensors()
        {
           
             return databaseAccess.SensorDBs.ToList();
        }

        public List<GroupDB> GetGroups()
        {
            return databaseAccess.GroupDBs.ToList();
        }

        public SensorDB GetSenor(int sensorId)
        {
            return databaseAccess.SensorDBs.Where(x => x.ID == sensorId).First();
        }

        public void UpdateSensors()
        {
            databaseAccess.SaveChanges();
        }

        public List<SensorDataDB> GetSensorReadings(int sensorID)
        {
            return databaseAccess.SensorDataDBs.Where(x => x.SensorID == sensorID).ToList();
        }
        public SensorDataDB GetSensorLastReading(int sensorID)
        {
            return databaseAccess.SensorDataDBs.Where(x => x.SensorID == sensorID).ToList().Last();
        }
        public List<SensorDataDB> GetSensorReadings(int sensorID, DateTime date)
        {
            return GetSensorReadings(sensorID).Where(x => x.TimeStamp.Date.CompareTo(date.Date) == 0).ToList();
        }

        public List<SensorDataDB> GetSensorReadings(int sensorID, DateTime fromDate, DateTime toDate)
        {
            return GetSensorReadings(sensorID).Where(x => x.TimeStamp.CompareTo(fromDate) >= 0 && x.TimeStamp.CompareTo(toDate) <= 0).ToList();
        }
        public void AddSensorData(SensorDataDB s)
        {
            databaseAccess.AddToSensorDataDBs(s);
            databaseAccess.SaveChanges();
        }

        public List<PresentableDataPoint> GetPresentableSensorReadings(int sensorID, DateTime fromTime, DateTime toTime)
        {
            List<PresentableDataPoint> DataPoints = new List<PresentableDataPoint>();
            List<SensorDataDB> temp = GetSensorReadings(sensorID, fromTime, toTime);
            foreach (var item in temp)
            {
                DataPoints.Add(new PresentableDataPoint(item));
            }
            return DataPoints;
        }

        public void Log(string Description, string MethodName = "NoMethodNameGiven", string ClassName = "NoClassNameGiven")
        {
            var newlog = new LogDB();
            newlog.Timestamp = DateTime.Now;
            newlog.Description = Description;
            newlog.Method = MethodName;
            newlog.Class = ClassName;
            databaseAccess.AddToLogDBs(newlog);
            databaseAccess.SaveChanges();

        }
        public static DataAccess GetInstance()
        {
            if (Instance == null)
            {

                Instance = new DataAccess();
              //  Instance.GetPresentableSensors();
            }
            return Instance;
        }
        public DateTime MinDate()
        {
           PresentableSensor p = GetPresentableSensors().First();
            return databaseAccess.SensorDataDBs.Where(x => x.SensorID == p.ID).ToList().First().TimeStamp;
        }
        public DateTime MaxDate()
        {
            PresentableSensor p = GetPresentableSensors().First();
            return databaseAccess.SensorDataDBs.Where(x => x.SensorID == p.ID).ToList().Last().TimeStamp;
        }

        public bool HasUser(String username)
        {
            return databaseAccess.UserDBs.Any(x => x.mail == username);
        }

        public bool isValidAccount(string username, string password)
        {
            UserDB user = databaseAccess.UserDBs.Where(x => x.mail == username).First();
            string salt = "VX4Zm368?c!gCn5SNDHyh2qvkQpuAUr-";
            string cypheredp = CalculateMD5Hash((password + salt));
            //user.password = cypheredp;
            //databaseAccess.SaveChanges();
            //return true;
            return user.password == cypheredp;
        }

        private string CalculateMD5Hash(string input)
        {
            // step 1, calculate MD5 hash from input
            MD5 md5 = MD5.Create();
            byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
            byte[] hash = md5.ComputeHash(inputBytes);

            // step 2, convert byte array to hex string
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                sb.Append(hash[i].ToString("x2"));
            }
            return sb.ToString();
        }
    }
}
